/**
 * 
 */
package com.ms.service.module.baccarat;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Queue;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ms.service.module.baccarat.bin.BacrBetType;
import com.xpec.c4.game.common.Helper;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.game.utility.GameUtility;

/**
 * 結算階段的資料
 * 
 * @author TW15010
 */
public class BacrCalculateScoreStepData {
	/** log4j object */
	private static final Log log = LogFactory.getLog(BacrCalculateScoreStepData.class);

	/**
	 * 輸贏結果
	 * <p>
	 * 只會是以下的值<br>
	 * {@link BacrBetType#BANKER}<br>
	 * {@link BacrBetType#PLAYER}<br>
	 * {@link BacrBetType#TIE}
	 */
	private int result;

	/**
	 * 是否有莊對
	 */
	private boolean bankerPair;

	/**
	 * 是否有閒對
	 */
	private boolean playerPair;

	/**
	 * 押閒的賠率
	 */
	private BigDecimal playerPayRate;

	/**
	 * 押莊的賠率
	 */
	private BigDecimal bankerPayRate;

	/**
	 * 押和的賠率
	 */
	private BigDecimal tiePayRate;

	/**
	 * 押閒對的賠率
	 */
	private BigDecimal playerPairPayRate;

	/**
	 * 押莊對的賠率
	 */
	private BigDecimal bankerPairPayRate;

	/**
	 * 所有有押注的玩家的得分資料<br>
	 * key: player id<br>
	 * value: score info
	 */
	private HashMap<GUID, BacrPlayerGetScoreInfo> playerScoreList = new HashMap<GUID, BacrPlayerGetScoreInfo>();

	/**
	 * 等待被處理的得分資料
	 * <p>
	 * 依照這個清單將得分派給玩家，處理一個就移除一個，直到清空為止
	 */
	private Queue<BacrPlayerGetScoreInfo> returnScoreProcQueue = new LinkedList<BacrPlayerGetScoreInfo>();

	/**
	 * 等待被處理的活動連勝得分資料<br>
	 * key: player id<br>
	 * value: 連勝活動得分資料
	 */
	private HashMap<GUID, BacrPlayerActivityCombosInfo> returnActivityCombosScoreMap = new HashMap<GUID, BacrPlayerActivityCombosInfo>();

	public void clear() {
		result = 0;
		bankerPair = false;
		playerPair = false;

		playerPayRate = BigDecimal.ZERO;
		bankerPayRate = BigDecimal.ZERO;
		tiePayRate = BigDecimal.ZERO;
		playerPairPayRate = BigDecimal.ZERO;
		bankerPairPayRate = BigDecimal.ZERO;

		playerScoreList.clear();
		returnScoreProcQueue.clear();
		returnActivityCombosScoreMap.clear();
	}

	public int getResult() {
		return result;
	}

	public void setResult(int result) {
		this.result = result;
	}

	public boolean isBankerPair() {
		return bankerPair;
	}

	public void setBankerPair(boolean bankerPair) {
		this.bankerPair = bankerPair;
	}

	public boolean isPlayerPair() {
		return playerPair;
	}

	public void setPlayerPair(boolean playerPair) {
		this.playerPair = playerPair;
	}

	public BigDecimal getPlayerPayRate() {
		return playerPayRate;
	}

	public void setPlayerPayRate(BigDecimal playerPayRate) {
		this.playerPayRate = playerPayRate;
	}

	public BigDecimal getBankerPayRate() {
		return bankerPayRate;
	}

	public void setBankerPayRate(BigDecimal bankerPayRate) {
		this.bankerPayRate = bankerPayRate;
	}

	public BigDecimal getTiePayRate() {
		return tiePayRate;
	}

	public void setTiePayRate(BigDecimal tiePayRate) {
		this.tiePayRate = tiePayRate;
	}

	public BigDecimal getPlayerPairPayRate() {
		return playerPairPayRate;
	}

	public void setPlayerPairPayRate(BigDecimal playerPairPayRate) {
		this.playerPairPayRate = playerPairPayRate;
	}

	public BigDecimal getBankerPairPayRate() {
		return bankerPairPayRate;
	}

	public void setBankerPairPayRate(BigDecimal bankerPairPayRate) {
		this.bankerPairPayRate = bankerPairPayRate;
	}

	public HashMap<GUID, BacrPlayerGetScoreInfo> getPlayerScoreList() {
		return playerScoreList;
	}

	public Queue<BacrPlayerGetScoreInfo> getReturnScoreProcQueue() {
		return returnScoreProcQueue;
	}

	/**
	 * 用押注類型取得指定部位的賠率
	 * 
	 * @param betType
	 *            {@link BacrBetType}
	 * @return
	 */
	public BigDecimal getPayRateByBetType(int betType) {
		BigDecimal payRate;

		switch (betType) {
		case BacrBetType.PLAYER:
			payRate = playerPayRate;
			break;
		case BacrBetType.BANKER:
			payRate = bankerPayRate;
			break;
		case BacrBetType.TIE:
			payRate = tiePayRate;
			break;
		case BacrBetType.PLAYER_PAIR:
			payRate = playerPairPayRate;
			break;
		case BacrBetType.BANKER_PAIR:
			payRate = bankerPairPayRate;
			break;
		default:
			payRate = BigDecimal.ZERO;
			if (log.isErrorEnabled()) {
				GameUtility.logErrorException(log, "invalid bet type " + betType);
			}
			break;
		}

		return payRate;
	}

	/**
	 * 取得所有玩家的總得分
	 * 
	 * @return
	 */
	public BigDecimal getTotalScore() {
		BigDecimal totalScore = BigDecimal.ZERO;

		for (Entry<GUID, BacrPlayerGetScoreInfo> entry : playerScoreList.entrySet()) {
			BacrPlayerGetScoreInfo score = entry.getValue();
			totalScore = Helper.add(totalScore, score.getTotalScore());
		}

		return totalScore;
	}

	public HashMap<GUID, BacrPlayerActivityCombosInfo> getReturnActivityCombosScoreMap() {
		return returnActivityCombosScoreMap;
	}
	
	/**
	 * 取得目前的勝負結果資料結構
	 * 
	 * @return
	 */
	public BacrGameResult getGameResult() {
		BacrGameResult gameResult = new BacrGameResult();
		gameResult.setWinnerType((byte) result);
		gameResult.setPlayerPair(playerPair);
		gameResult.setBankerPair(bankerPair);

		return gameResult;
	}
	
	/**
	 * 取得所有玩家活動連勝得分
	 */
	public long getAllActivityCombosScore(){
		long result = 0L;
		
		if(returnActivityCombosScoreMap.size() == 0)
			return result;
		else{
			for(BacrPlayerActivityCombosInfo activityCombosInfo : returnActivityCombosScoreMap.values()){
				if(activityCombosInfo.getActivityCombosScore() > 0){
					result += activityCombosInfo.getActivityCombosScore();
				}
			}
		}
		
		return result;
	}
}